<HTML>
<HEAD>
<TITLE>BClipboard 使用案例与实现细节</TITLE>
</HEAD>

<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">

<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">

<H1>BClipboard 使用案例与实现细节：</H1>

<P>本文档描述BClipboard接口及其基本实现方式。
文档包含以下章节：</P>

<OL>
<LI><A HREF="#interface">BClipboard 接口</A></LI>
<LI><A HREF="#usecases">BClipboard 使用案例</A></LI>
<LI><A HREF="#implement">BClipboard 实现</A></LI>
</OL>

<A NAME="interface"></A><H2>BClipboard 接口：</H2>

<P>BClipboard类提供了一个命名、系统级的临时存储资源接口。
通过BApplication对象提供的be_clipboard变量(或通过构造名为"system"的剪贴板)可以访问系统剪贴板。
关于BClipboard接口的最佳信息来源可以在
<A HREF="https://www.haiku-os.org/legacy-docs/bebook/BClipboard.html">Be Book这里</A>找到。
</P>

<A NAME="usecases"></A><H2>BClipboard 使用案例：</H2>

<P>以下使用案例涵盖了BClipboard的功能：</P>

<OL>
<LI><P><B>构造：</B> BClipboard构造时接受一个或两个参数。
必须提供名称来标识剪贴板。discard参数表示是否应在重启间丢弃剪贴板数据。
discard参数默认为false，但由于尚未实现跨重启保存剪贴板数据的功能，此参数目前无意义。
构造后，队列为空。</P></LI>

<LI><P><B>析构：</B> 析构函数会销毁BClipboard对象，但系统级剪贴板本身不受影响。</P></LI>

<LI><P><B>写入剪贴板1：</B> 
写入数据的标准流程包括：通过Lock()锁定剪贴板，通过Clear()清除数据，
向剪贴板消息添加数据，通过Commit()提交数据，最后通过Unlock()解锁剪贴板。
</P></LI>

<LI><P><B>写入剪贴板2：</B> 
要写入的数据不是直接添加到BClipboard对象，而是添加到BClipboard的数据消息中。
通过调用BClipboard::Data()获取消息。数据以B_MIME_TYPE类型的字段添加。
字段名称对应数据的MIME类型。如果添加多个字段，它们应包含相同数据但格式化为不同MIME类型。
</P></LI>

<LI><P><B>写入剪贴板3：</B> 
如果在调用Commit()之前希望撤销写入过程，必须调用Revert()。
否则，对剪贴板的更改将保留在BClipboard对象中。
</P></LI>

<LI><P><B>读取剪贴板1：</B> 
读取数据的标准流程包括：通过Lock()锁定剪贴板，从剪贴板数据消息获取数据，
然后通过Unlock()解锁剪贴板。
</P></LI>

<LI><P><B>读取剪贴板2：</B> 
通过调用BClipboard::Data()获取数据消息。使用BMessage::FindData获取指定MIME类型的数据。
</P></LI>

<LI><P><B>读取剪贴板3：</B> 
调用Lock()时会从系统上传数据，因此在Lock()和Data()调用之间写入剪贴板的任何数据
都不会包含在数据消息中。
</P></LI>

<LI><P><B>读取剪贴板4：</B> 
可以在调用FindData之前先调用Unlock()解锁剪贴板。
</P></LI>

<LI><P><B>清除：</B> 
Clear()函数用于从剪贴板移除所有数据，通常在写入新数据前使用。
如果BClipboard未锁定，Clear()返回B_ERROR；如果已锁定，返回B_OK。
</P></LI>

<LI><P><B>提交：</B> 
Commit()函数用于将数据从BClipboard上传到系统。调用Commit()后，数据立即可供其他应用使用。
如果BClipboard未锁定，Commit()返回B_ERROR；如果已锁定，返回B_OK。
</P></LI>

<LI><P><B>撤销：</B> 
Revert()函数用于将BClipboard中的数据与系统同步。仅在开始修改数据消息后希望撤销更改时需要。
如果BClipboard未锁定，Revert()返回B_ERROR；如果已锁定，返回B_OK。
</P></LI>

<LI><P><B>访问数据：</B> 
Data()用于获取指向BClipboard数据消息的指针。可以直接读写消息，但不能释放或分发消息。
如果BClipboard未锁定，Data()返回NULL。
</P></LI>

<LI><P><B>访问数据源：</B> 
DataSource()用于获取指向最后向剪贴板提交数据的BApplication的BMessenger。
调用DataSource()时不需要锁定BClipboard。
</P></LI>

<LI><P><B>获取计数：</B> 
计数指数据上传到剪贴板的次数。
有两个计数函数。SystemCount()返回从系统获取的最新计数。
Count()返回缓存计数。缓存计数在创建BClipboard时设为零，
并在调用Lock()或Commit()时更新。
</P></LI>

<LI><P><B>锁定：</B>
Lock()用于将数据从系统上传到BClipboard对象，并阻止应用程序中的其他线程使用它。
在读取或写入BClipboard数据前必须调用。如果BClipboard已锁定，它会阻塞。
如果BClipboard成功锁定则返回true，如果在阻塞期间BClipboard被删除则返回false。
</P></LI>

<LI><P><B>解锁：</B>
Unlock()用于解锁BClipboard，允许应用程序中的其他线程使用它。
</P></LI>

<LI><P><B>检查锁定状态：</B>
IsLocked()在当前线程锁定BClipboard时返回true，如果未锁定或被其他线程锁定则返回false。
</P></LI>

<LI><P><B>检查剪贴板名称：</B>
Name()返回包含剪贴板名称的字符串。调用Name()时不需要锁定BClipboard。
</P></LI>

<LI><P><B>监视剪贴板：</B> 
StartWatching和StopWatching用于启用和禁用对剪贴板的监视。当剪贴板更改时，
会向StartWatching调用中指定的目标发送B_CLIPBOARD_CHANGED消息。
</P></LI>

</OL>

<A NAME="implement"></A><H2>BClipboard 实现：</H2>

<P>
BClipboard类通过BClipboard、Registrar和与Registrar关联的Clipboard Handler之间的消息传递系统实现。
消息传递协议的详细信息见Registrar文档。
</P>

</BODY>
</HTML>